import {expect} from "assertions"

import {catmullrom_spline} from "@bokehjs/core/util/interpolation"

describe("core/util/interpolation module", () => {

  describe("should support centripetal Catmull-Rom splines", () => {

    it("where start != end, T=20, tension=0.5, closed=false", () => {
      const x = new Float64Array([1, 3, 7, 8])
      const y = new Float64Array([1, 8, 3, 5])

      const [xt, yt] = catmullrom_spline(x, y, 20, 0.5, false)

      const _xt = new Float64Array([
        1, 1.0525000095367432, 1.1100000143051147, 1.1725000143051147, 1.2400000095367432, 1.3125, 1.3899999856948853,
        1.472499966621399, 1.559999942779541, 1.652500033378601, 1.75, 1.8524999618530273, 1.9600000381469727,
        2.072499990463257, 2.190000057220459, 2.3125, 2.440000057220459, 2.572499990463257, 2.7100000381469727,
        2.8524999618530273, 3, 3, 3.158437490463257, 3.3324999809265137, 3.520312547683716, 3.7200000286102295,
        3.9296875, 4.147500038146973, 4.371562480926514, 4.599999904632568, 4.830937385559082, 5.0625, 5.292812347412109,
        5.519999980926514, 5.7421875, 5.957499980926514, 6.1640625, 6.360000133514404, 6.543437480926514, 6.712500095367432,
        6.865312576293945, 7, 7, 7.118875026702881, 7.22599983215332, 7.32212495803833, 7.4079999923706055, 7.484375,
        7.552000045776367, 7.611624717712402, 7.664000034332275, 7.709875106811523, 7.75, 7.785124778747559, 7.815999984741211,
        7.843374729156494, 7.868000030517578, 7.890625, 7.9120001792907715, 7.932875156402588, 7.953999996185303, 7.9761247634887695, 8,
      ])
      const _yt = new Float64Array([
        1, 1.2063125371932983, 1.4704999923706055, 1.7854374647140503, 2.1440000534057617, 2.5390625, 2.9635000228881836,
        3.4101874828338623, 3.871999979019165, 4.341812610626221, 4.8125, 5.276937484741211, 5.728000164031982,
        6.158562183380127, 6.561500072479248, 6.9296875, 7.25600004196167, 7.5333123207092285, 7.754499912261963,
        7.912437438964844, 8, 8, 8.01243782043457, 7.954500198364258, 7.833312511444092, 7.656000137329102, 7.4296875,
        7.161499977111816, 6.858562469482422, 6.5279998779296875, 6.176937580108643, 5.8125, 5.441812515258789,
        5.072000026702881, 4.7101874351501465, 4.363500118255615, 4.0390625, 3.744000196456909, 3.4854373931884766,
        3.2704999446868896, 3.1063125133514404, 3, 3, 2.9444375038146973, 2.92549991607666, 2.939812421798706,
        2.9839999675750732, 3.0546875, 3.1484999656677246, 3.2620623111724854, 3.3919999599456787, 3.5349373817443848,
        3.6875, 3.8463125228881836, 4.007999897003174, 4.169187545776367, 4.326499938964844, 4.4765625, 4.616000175476074,
        4.7414374351501465, 4.8495001792907715, 4.936812400817871, 5,
      ])

      expect(xt).to.be.similar(_xt)
      expect(yt).to.be.similar(_yt)
    })

    it("where start != end, T=20, tension=0.5, closed=true", () => {
      const x = new Float64Array([1, 3, 7, 8])
      const y = new Float64Array([1, 8, 3, 5])

      const [xt, yt] = catmullrom_spline(x, y, 20, 0.5, true)

      const _xt = new Float64Array([
        1, 0.8945624828338623, 0.8264999985694885, 0.7931874990463257, 0.7919999957084656, 0.8203125, 0.875499963760376,
        0.9549374580383301, 1.055999994277954, 1.1760624647140503, 1.3125, 1.4626874923706055, 1.624000072479248,
        1.7938123941421509, 1.969499945640564, 2.1484375, 2.328000068664551, 2.5055625438690186, 2.678499937057495,
        2.8441874980926514, 3, 3, 3.158437490463257, 3.3324999809265137, 3.520312547683716, 3.7200000286102295,
        3.9296875, 4.147500038146973, 4.371562480926514, 4.599999904632568, 4.830937385559082, 5.0625, 5.292812347412109,
        5.519999980926514, 5.7421875, 5.957499980926514, 6.1640625, 6.360000133514404, 6.543437480926514, 6.712500095367432,
        6.865312576293945, 7, 7, 7.127187252044678, 7.257500171661377, 7.389062404632568, 7.520000457763672, 7.6484375,
        7.772500038146973, 7.890312194824219, 8, 8.099687576293945, 8.1875, 8.26156234741211, 8.319999694824219,
        8.360937118530273, 8.382499694824219, 8.3828125, 8.360000610351562, 8.312187194824219, 8.237500190734863,
        8.134062767028809, 8, 8, 7.819812297821045, 7.583499908447266, 7.29743766784668, 6.968000411987305, 6.6015625,
        6.2044997215271, 5.783187389373779, 5.343999862670898, 4.893312454223633, 4.4375, 3.9829375743865967,
        3.5360000133514404, 3.103062391281128, 2.690500020980835, 2.3046875, 1.9520000219345093, 1.63881254196167,
        1.371500015258789, 1.1564375162124634, 1,
      ])
      const _yt = new Float64Array([
        1, 1.1160625219345093, 1.308500051498413, 1.5686874389648438, 1.8880000114440918, 2.2578125, 2.6695001125335693,
        3.1144373416900635, 3.5839998722076416, 4.0695624351501465, 4.5625, 5.054187774658203, 5.5360002517700195,
        5.999312400817871, 6.435499668121338, 6.8359375, 7.192000389099121, 7.495062351226807, 7.736499786376953,
        7.907687187194824, 8, 8, 8.01243782043457, 7.954500198364258, 7.833312511444092, 7.656000137329102, 7.4296875,
        7.161499977111816, 6.858562469482422, 6.5279998779296875, 6.176937580108643, 5.8125, 5.441812515258789,
        5.072000026702881, 4.7101874351501465, 4.363500118255615, 4.0390625, 3.744000196456909, 3.4854373931884766,
        3.2704999446868896, 3.1063125133514404, 3, 3, 2.9491875171661377, 2.94350004196167, 2.978062391281128,
        3.0480000972747803, 3.1484375, 3.2744998931884766, 3.4213123321533203, 3.5840001106262207, 3.757687568664551,
        3.9375, 4.118562698364258, 4.296000003814697, 4.464937210083008, 4.620500087738037, 4.7578125, 4.872000217437744,
        4.958187580108643, 5.011499881744385, 5.02706241607666, 5, 5, 4.922312259674072, 4.793499946594238, 4.619937419891357,
        4.4079999923706055, 4.1640625, 3.8945000171661377, 3.605687379837036, 3.303999900817871, 2.99581241607666, 2.6875,
        2.385437488555908, 2.0959999561309814, 1.8255624771118164, 1.5805000066757202, 1.3671875, 1.1920000314712524,
        1.0613124370574951, 0.9815000295639038, 0.9589374661445618, 1,
      ])

      expect(xt).to.be.similar(_xt)
      expect(yt).to.be.similar(_yt)
    })

    it("where start == end, T=20, tension=0.5, closed=false", () => {
      const x = new Float64Array([1, 3, 7, 8, 1])
      const y = new Float64Array([1, 8, 3, 5, 1])

      const [xt, yt] = catmullrom_spline(x, y, 20, 0.5, false)

      const _xt = new Float64Array([
        1, 1.0525000095367432, 1.1100000143051147, 1.1725000143051147, 1.2400000095367432, 1.3125, 1.3899999856948853,
        1.472499966621399, 1.559999942779541, 1.652500033378601, 1.75, 1.8524999618530273, 1.9600000381469727,
        2.072499990463257, 2.190000057220459, 2.3125, 2.440000057220459, 2.572499990463257, 2.7100000381469727,
        2.8524999618530273, 3, 3, 3.158437490463257, 3.3324999809265137, 3.520312547683716, 3.7200000286102295,
        3.9296875, 4.147500038146973, 4.371562480926514, 4.599999904632568, 4.830937385559082, 5.0625, 5.292812347412109,
        5.519999980926514, 5.7421875, 5.957499980926514, 6.1640625, 6.360000133514404, 6.543437480926514, 6.712500095367432,
        6.865312576293945, 7, 7, 7.127187252044678, 7.257500171661377, 7.389062404632568, 7.520000457763672, 7.6484375,
        7.772500038146973, 7.890312194824219, 8, 8.099687576293945, 8.1875, 8.26156234741211, 8.319999694824219,
        8.360937118530273, 8.382499694824219, 8.3828125, 8.360000610351562, 8.312187194824219, 8.237500190734863,
        8.134062767028809, 8, 8, 7.822187423706055, 7.59250020980835, 7.316562652587891, 7, 6.6484375, 6.267499923706055,
        5.862812519073486, 5.440000057220459, 5.004687309265137, 4.5625, 4.119062423706055, 3.680000066757202,
        3.2509374618530273, 2.8375000953674316, 2.4453125, 2.080000162124634, 1.7471874952316284, 1.4524999856948853,
        1.201562523841858, 1,
      ])
      const _yt = new Float64Array([
        1, 1.2063125371932983, 1.4704999923706055, 1.7854374647140503, 2.1440000534057617, 2.5390625, 2.9635000228881836,
        3.4101874828338623, 3.871999979019165, 4.341812610626221, 4.8125, 5.276937484741211, 5.728000164031982,
        6.158562183380127, 6.561500072479248, 6.9296875, 7.25600004196167, 7.5333123207092285, 7.754499912261963,
        7.912437438964844, 8, 8, 8.01243782043457, 7.954500198364258, 7.833312511444092, 7.656000137329102, 7.4296875,
        7.161499977111816, 6.858562469482422, 6.5279998779296875, 6.176937580108643, 5.8125, 5.441812515258789,
        5.072000026702881, 4.7101874351501465, 4.363500118255615, 4.0390625, 3.744000196456909, 3.4854373931884766,
        3.2704999446868896, 3.1063125133514404, 3, 3, 2.9491875171661377, 2.94350004196167, 2.978062391281128,
        3.0480000972747803, 3.1484375, 3.2744998931884766, 3.4213123321533203, 3.5840001106262207, 3.757687568664551,
        3.9375, 4.118562698364258, 4.296000003814697, 4.464937210083008, 4.620500087738037, 4.7578125, 4.872000217437744,
        4.958187580108643, 5.011499881744385, 5.02706241607666, 5, 5, 4.930624961853027, 4.824999809265137, 4.686874866485596,
        4.519999980926514, 4.328125, 4.114999771118164, 3.8843748569488525, 3.640000104904175, 3.385625123977661, 3.125,
        2.861875057220459, 2.5999999046325684, 2.3431248664855957, 2.0950000286102295, 1.859375, 1.6400001049041748,
        1.4406249523162842, 1.2649999856948853, 1.1168749332427979, 1,
      ])

      expect(xt).to.be.similar(_xt)
      expect(yt).to.be.similar(_yt)
    })
  })
})
